package com.love.marriage.orderInfo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.love.marriage.TecentIm.service.ChatService;
import com.love.marriage.cloud.service.WechatService;
import com.love.marriage.cloud.vo.RedPacketResultVo;
import com.love.marriage.cloud.vo.RedPacketVo;
import com.love.marriage.common.enums.ResultEnum;
import com.love.marriage.common.enums.TransactionSource;
import com.love.marriage.common.enums.TransactionType;
import com.love.marriage.common.event.UserInviteRedPacketEvent;
import com.love.marriage.common.exceptions.SystemException;
import com.love.marriage.common.exceptions.UserException;
import com.love.marriage.datingInfo.service.DatingInfoService;
import com.love.marriage.datingInfo.vo.DatingInfoResVo;
import com.love.marriage.datingInfo.vo.DatingInfoVo;
import com.love.marriage.datingRegistrationInfo.entity.DatingRegistrationInfo;
import com.love.marriage.datingRegistrationInfo.service.DatingRegistrationInfoService;
import com.love.marriage.datingRegistrationInfo.vo.DatingRegistrationInfoVo;
import com.love.marriage.eventInfo.service.EventInfoService;
import com.love.marriage.eventInfo.vo.EventInfoVo;
import com.love.marriage.eventRegistrationInfo.entity.EventRegistrationInfo;
import com.love.marriage.eventRegistrationInfo.service.EventRegistrationInfoService;
import com.love.marriage.eventRegistrationInfo.vo.EventRegistrationInfoVo;
import com.love.marriage.matchmakerInfo.service.MatchmakerInfoService;
import com.love.marriage.matchmakerInfo.vo.MatchmakerInfoVo;
import com.love.marriage.membershipConfiguration.service.MembershipConfigurationService;
import com.love.marriage.membershipConfiguration.vo.MembershipConfigurationVo;
import com.love.marriage.offlineServiceProvider.service.OfflineServiceProviderService;
import com.love.marriage.offlineServiceProvider.vo.OfflineServiceProviderVo;
import com.love.marriage.orderInfo.service.OrderInfoService;
import com.love.marriage.orderInfo.service.PayInfoService;
import com.love.marriage.orderInfo.vo.OrderInfoVo;
import com.love.marriage.rechargePackageInfo.service.RechargePackageInfoService;
import com.love.marriage.rechargePackageInfo.vo.RechargePackageInfoVo;
import com.love.marriage.userActivityInfo.service.UserActivityInfoService;
import com.love.marriage.userActivityInfo.vo.UserActivityInfoVo;
import com.love.marriage.userBalanceInfo.service.UserBalanceInfoService;
import com.love.marriage.userBalanceInfo.vo.UserBalanceInfoAddVo;
import com.love.marriage.userBalanceInfo.vo.UserBalanceInfoVo;
import com.love.marriage.userCallRetrieval.service.UserCallRetrievalService;
import com.love.marriage.userCommissionBalance.service.CommissionCommonService;
import com.love.marriage.userInfo.mapper.UserInfoMapper;
import com.love.marriage.userInfo.vo.UserInfoVo;
import com.love.marriage.userMembershipInfo.service.UserMembershipInfoService;
import com.love.marriage.userMembershipInfo.vo.UserMembershipInfoVo;
import com.love.marriage.userTransactionInfo.service.UserTransactionInfoService;
import com.love.marriage.userTransactionInfo.vo.UserTransactionInfoVo;
import com.love.marriage.utils.OrderCodeUtils;
import com.love.marriage.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class PayInfoServiceImpl implements PayInfoService {


    private final OrderInfoService orderInfoService;

    private final WechatService wechatService;

    private final RechargePackageInfoService rechargePackageInfoService;

    private final MembershipConfigurationService membershipConfigurationService;

    @Autowired
    @Qualifier("miniAppPayService")
    private WxPayService wxPayService;

    private final UserBalanceInfoService userBalanceInfoService;

    private final UserMembershipInfoService userMembershipInfoService;

    private final DatingInfoService datingInfoService;

    private final ChatService chatService;

    private final DatingRegistrationInfoService datingRegistrationInfoService;

    private final EventRegistrationInfoService eventRegistrationInfoService;

    private final UserInfoMapper userInfoMapper;

    private final CommissionCommonService commissionCommonService;

    private final MatchmakerInfoService matchmakerInfoService;

    private final UserCallRetrievalService userCallRetrievalService;

    private final UserTransactionInfoService userTransactionInfoService;

    private final OfflineServiceProviderService offlineServiceProviderService;

    private final UserActivityInfoService userActivityInfoService;

    private final EventInfoService eventInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayUnifiedOrderV3Result.JsapiResult addAmount(UserBalanceInfoAddVo userBalanceInfoAddVo) throws WxPayException {
        if (userBalanceInfoAddVo.getUserId() == null) {
            throw new RuntimeException("充值金额不能为空！");
        }
        // 如果充值包id不为空，则查询充值包记录
        // 支付金额
        BigDecimal payAmount;
        if (userBalanceInfoAddVo.getRechargePackageId() != null) {
            RechargePackageInfoVo rechargePackageInfoVo = rechargePackageInfoService.queryRechargePackageInfo(userBalanceInfoAddVo.getRechargePackageId());
            payAmount = rechargePackageInfoVo.getAmount();
        } else {
            payAmount = userBalanceInfoAddVo.getAmount();
        }
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setUserId(userBalanceInfoAddVo.getUserId());
        orderInfoVo.setOrderNumber(OrderCodeUtils.generatorOrderNumber("CZ"));
        orderInfoVo.setTotalAmount(payAmount);
        orderInfoVo.setStatus("PENDING");
        orderInfoVo.setPaymentMethod("WECHAT_APP");
        orderInfoVo.setPaymentTime(LocalDateTime.now());
        orderInfoVo.setOrderDescription("余额充值");
        orderInfoVo.setBusinessId(userBalanceInfoAddVo.getRechargePackageId());
        orderInfoVo.setType("payBalance");
        OrderInfoVo dbOrder = orderInfoService.addOrderInfo(orderInfoVo);
        return wechatService.unifiedOrder(userBalanceInfoAddVo.getUserId(), payAmount.multiply(new BigDecimal("100")).intValue(),
                "payBalance", dbOrder.getOrderNumber(), dbOrder.getOrderDescription());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayUnifiedOrderV3Result.JsapiResult membership(UserMembershipInfoVo userMembershipInfoVo) throws WxPayException {
        // 查询会员配置信息
        MembershipConfigurationVo membershipConfigurationVo = membershipConfigurationService.queryMembershipConfiguration(userMembershipInfoVo.getMembershipId());
        
        // 查询用户当前会员信息，进行会员等级校验
        UserMembershipInfoVo currentMembership = userMembershipInfoService.queryUserMembershipInfoByUserId(userMembershipInfoVo.getUserId());
        
        // 如果用户已有会员，需要验证是否可以升级
        if (currentMembership != null) {
            // 查询用户当前会员的配置信息
            MembershipConfigurationVo currentMembershipConfig = membershipConfigurationService.queryMembershipConfiguration(currentMembership.getMembershipId());
            // 只能升级到更高等级的会员或平级续费，不支持降级
            if (membershipConfigurationVo.getOrderNum() < currentMembershipConfig.getOrderNum()) {
                throw new UserException("4000001", "不支持降级为低级别的会员");
            }
        }
        
        BigDecimal payAmount = membershipConfigurationVo.getCurrentPrice() == null ? membershipConfigurationVo.getOriginalPrice() : membershipConfigurationVo.getCurrentPrice();
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setUserId(userMembershipInfoVo.getUserId());
        orderInfoVo.setOrderNumber(OrderCodeUtils.generatorOrderNumber("HY"));
        orderInfoVo.setTotalAmount(payAmount);
        orderInfoVo.setStatus("PENDING");
        orderInfoVo.setPaymentMethod("WECHAT_APP");
        orderInfoVo.setPaymentTime(LocalDateTime.now());
        orderInfoVo.setOrderDescription("会员购买");
        orderInfoVo.setBusinessId(userMembershipInfoVo.getMembershipId());
        orderInfoVo.setSource(userMembershipInfoVo.getSource());
        orderInfoVo.setType("membership");
        OrderInfoVo dbOrder = orderInfoService.addOrderInfo(orderInfoVo);
        if ("end".equals(userMembershipInfoVo.getSource())) {
            return null;
        }
        return wechatService.unifiedOrder(userMembershipInfoVo.getUserId(), payAmount.multiply(new BigDecimal("100")).intValue(),
                "membership", dbOrder.getOrderNumber(), dbOrder.getOrderDescription());
    }
    
    /**
     * 获取会员等级，用于比较会员升级权限
     * 等级值说明：季度会员 (1) < 年度会员 (2) < 定制体验会员 (3) < 悬赏征婚会员 (4)
     * @param membershipCode 会员编码 (quarter/year/customize/four_year)
     * @return 会员等级值，值越大表示等级越高
     */
    private int getMembershipLevel(String membershipCode) {
        // 根据会员编码返回等级值，用于升级验证
        switch (membershipCode) {
            case "quarter":
                return 1; // 季度会员
            case "year":
                return 2; // 年度会员
            case "customize":
                return 3; // 定制体验会员
            case "four_year":
                return 4; // 悬赏征婚会员
            default:
                return 0; // 未知等级
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object notify(String xmlData) throws WxPayException {
        try {
            log.info("微信支付回调结果: {}", xmlData);
            if (xmlData == null || xmlData.trim().isEmpty()) {
                log.error("微信支付回调通知中的xmlData为空或无效");
                throw new WxPayException("微信支付通知数据为空");
            }
            WxPayNotifyV3Result notifyResult;
            WxPayNotifyV3Result.DecryptNotifyResult result;
            try {
                // 解析 XML 数据
                notifyResult = wxPayService.parseOrderNotifyV3Result(xmlData, null);
                if (notifyResult.getResult() == null) {
                    log.error("微信支付回调通知解析失败, xmlData: {}", xmlData);
                    throw new WxPayException("微信支付通知解析失败");
                }
                result = notifyResult.getResult();
            } catch (WxPayException e) {
                log.error("微信支付回调通知解析失败, xmlData: {}", xmlData, e);
                throw new WxPayException("微信支付通知解析失败", e);
            } catch (Exception e) {
                log.error("微信支付回调通知解析过程中发生未知错误, xmlData: {}", xmlData, e);
                throw new WxPayException("微信支付通知解析过程中发生未知错误", e);
            }
            log.info("微信支付回调结果: {}", notifyResult);
            String orderId = result.getOutTradeNo();
            String attach = result.getAttach();
            log.info("微信支付回调结果: orderId: {}, attach: {}", orderId, attach);
            OrderInfoVo orderInfoVo = orderInfoService.queryOrderInfoByOrderNumber(orderId);
            log.info("微信支付回调结果: orderInfoVo: {}", orderInfoVo);
            if (orderInfoVo == null) {
                log.error("订单不存在: {}", orderId);
                return new SystemException(ResultEnum.ORDER_NO_EXISTS);
            }
            if ("PAID".equals(orderInfoVo.getStatus())) {
                log.error("订单已支付: {}", orderId);
                return new SystemException(ResultEnum.ORDER_PAID);
            }
            orderInfoVo.setStatus("PAID");
            orderInfoService.updateOrderInfo(orderInfoVo);
            return getBack(attach, orderInfoVo, true);
        } catch (WxPayException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Object notify(String orderId, String attach) throws Exception {
        log.info("微信支付回调结果: orderId: {}, attach: {}", orderId, attach);
        OrderInfoVo orderInfoVo = orderInfoService.queryOrderInfoByOrderNumber(orderId);
        if (orderInfoVo == null) {
            log.error("订单不存在: {}", orderId);
            return new SystemException(ResultEnum.ORDER_NO_EXISTS);
        }
        if ("PAID".equals(orderInfoVo.getStatus())) {
            log.error("订单已支付: {}", orderId);
            return new SystemException(ResultEnum.ORDER_PAID);
        }
        orderInfoVo.setStatus("PAID");
        orderInfoService.updateOrderInfo(orderInfoVo);
        return getBack(attach, orderInfoVo, true);
    }

    @Override
    public Object notify(String orderId, String attach, Boolean commission) throws Exception {
        log.info("微信支付回调结果: orderId: {}, attach: {}", orderId, attach);
        OrderInfoVo orderInfoVo = orderInfoService.queryOrderInfoByOrderNumber(orderId);
        if (orderInfoVo == null) {
            log.error("订单不存在: {}", orderId);
            return new SystemException(ResultEnum.ORDER_NO_EXISTS);
        }
        if ("PAID".equals(orderInfoVo.getStatus())) {
            log.error("订单已支付: {}", orderId);
            return new SystemException(ResultEnum.ORDER_PAID);
        }
        orderInfoVo.setStatus("PAID");
        orderInfoService.updateOrderInfo(orderInfoVo);
        return getBack(attach, orderInfoVo, commission);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Object getBack(String attach, OrderInfoVo orderInfoVo, Boolean commission) throws Exception {
        // 判断当前人是否有推荐人，如果有则回佣
        // 添加二级分销
        if (commission != null && commission) {
            List<UserInfoVo> instrUser = userInfoMapper.queryUserInstrInfo(orderInfoVo.getUserId());
            if (instrUser != null && !instrUser.isEmpty() && instrUser.get(0).getIntroUserId() != null) {
                commissionCommonService.addTwoLevelCommission(orderInfoVo.getUserId(), orderInfoVo.getTotalAmount(), orderInfoVo.getId(), attach);
            }
            // 如果用户有介绍人，添加合伙人收益
            if (instrUser != null && !instrUser.isEmpty() && instrUser.get(0).getIntroUserId() != null) {
                commissionCommonService.addPartnerCommission(orderInfoVo.getUserId(), orderInfoVo.getTotalAmount(), orderInfoVo.getId());
            }
        }
        UserTransactionInfoVo userTransactionInfoVo = new UserTransactionInfoVo();
        userTransactionInfoVo.setUserId(orderInfoVo.getUserId());
        userTransactionInfoVo.setTransactionAmount(orderInfoVo.getTotalAmount());
        userTransactionInfoVo.setTransactionTime(LocalDateTime.now());
        userTransactionInfoVo.setTransactionSource(TransactionSource.MONEY.getCode());
        userTransactionInfoVo.setTransactionType(TransactionType.MEMBERSHIP_PURCHASE.getCode());
        userTransactionInfoVo.setDescription(orderInfoVo.getOrderDescription());
        userTransactionInfoVo.setOrderId(orderInfoVo.getId());
        Object res = null;
        switch (attach) {
            case "membership":
                UserMembershipInfoVo resMembership = userMembershipInfoService.membershipBack(orderInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resMembership.getId());
                res = resMembership;
                break;
            case "payBalance":
                UserBalanceInfoVo resPayBalance = userBalanceInfoService.addAmountBack(orderInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resPayBalance.getId());
                res = resPayBalance;
                break;
            case "getPhone":
            case "getPhone1":
            case "getPhone2":
            case "getPhone3":
            case "getPhone0":
                // 更新用户查看手机号次数
                res = userCallRetrievalService.addUserCallRetrievalCount(orderInfoVo.getUserId());
                break;
            case "chat":
                res = chatService.sendMessageMoney(orderInfoVo.getUserId(), orderInfoVo.getBusinessId(), orderInfoVo.getBusinessInfo());
                break;
            case "create_dating":
                DatingInfoVo datingInfoVo = JSONObject.parseObject(orderInfoVo.getBusinessInfo(), DatingInfoVo.class);
                DatingInfoVo resDating = datingInfoService.addDatingInfoBack(datingInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resDating.getId());
                res = resDating;
                break;
            case "join_dating":
                DatingRegistrationInfoVo datingRegistrationInfoVo = JSONObject.parseObject(orderInfoVo.getBusinessInfo(), DatingRegistrationInfoVo.class);
                if (datingRegistrationInfoVo == null) {
                    datingRegistrationInfoVo = new DatingRegistrationInfoVo();
                    datingRegistrationInfoVo.setUserId(orderInfoVo.getUserId());
                    datingRegistrationInfoVo.setDatingId(orderInfoVo.getBusinessId());
                }
                datingRegistrationInfoVo.setPayAmount(orderInfoVo.getTotalAmount());
                DatingRegistrationInfoVo resDatingRegistration = datingRegistrationInfoService.addDatingRegistrationInfoBack(datingRegistrationInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resDatingRegistration.getId());
                res = resDatingRegistration;
                break;
            // 参加活动
            case "join_event":
                EventRegistrationInfoVo eventRegistrationInfoVo = JSONObject.parseObject(orderInfoVo.getBusinessInfo(), EventRegistrationInfoVo.class);
                if (eventRegistrationInfoVo == null) {
                    eventRegistrationInfoVo = new EventRegistrationInfoVo();
                    eventRegistrationInfoVo.setUserId(orderInfoVo.getUserId());
                    eventRegistrationInfoVo.setEventId(orderInfoVo.getBusinessId());
                }
                eventRegistrationInfoVo.setPaymentAmount(orderInfoVo.getTotalAmount());
                EventRegistrationInfoVo resEventRegistration = eventRegistrationInfoService.addEventRegistrationInfoBack(eventRegistrationInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resEventRegistration.getId());
                res = resEventRegistration;
                break;
            // 添加红娘信息保存
            case "matchmaker_save":
                MatchmakerInfoVo matchmakerInfoVo = JSONObject.parseObject(orderInfoVo.getBusinessInfo(), MatchmakerInfoVo.class);
                matchmakerInfoVo.setStatus(2);
                MatchmakerInfoVo resMatchmaker = matchmakerInfoService.addInfo(matchmakerInfoVo);
                userTransactionInfoVo.setRelatedBusinessId(resMatchmaker.getId());
                res = resMatchmaker;
                break;
            case "partner":
                OfflineServiceProviderVo offlineServiceProviderVo = JSONObject.parseObject(orderInfoVo.getBusinessInfo(), OfflineServiceProviderVo.class);
                offlineServiceProviderVo.setStatus(2);
                OfflineServiceProviderVo resOfflineService = offlineServiceProviderService.addInfo(offlineServiceProviderVo);
                userTransactionInfoVo.setRelatedBusinessId(resOfflineService.getId());
                res = resOfflineService;
        }
        userTransactionInfoService.addUserTransactionInfo(userTransactionInfoVo);
        return res;
    }

    // 处理发送红包
    @EventListener
    public void handleUserInviteRedPacket(UserInviteRedPacketEvent event) throws Exception {
        log.info("邀请有礼：处理发送红包事件:{}", JSONObject.toJSONString(event));
        // 如果邀请人没有关注公众号，则将金钱存到回佣记录中
        RedPacketVo redPacketVo = event.getRedPacketVo();
        UserInfoVo userInfoVo = userInfoMapper.queryUserInfo(redPacketVo.getUserId());
        // 如果邀请人不存在，则直接返回
        if (userInfoVo == null) {
            return;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        String orderNumber = "HB" + timestamp;
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setUserId(redPacketVo.getUserId());
        orderInfoVo.setOrderNumber(orderNumber);
        orderInfoVo.setTotalAmount(redPacketVo.getAmount());
        orderInfoVo.setStatus("PENDING");
        orderInfoVo.setPaymentMethod("GZH_APP");
        orderInfoVo.setPaymentTime(LocalDateTime.now());
        orderInfoVo.setOrderDescription(redPacketVo.getRemark());
        orderInfoVo.setBusinessId(redPacketVo.getInvitedUserId());
        orderInfoVo.setSource("gzh_redPacket");
        orderInfoVo.setType("redPacket");
        orderInfoVo.setBusinessInfo(JSONObject.toJSONString(redPacketVo));
        redPacketVo.setMchBillNo(orderNumber);
        // 添加订单信息
        OrderInfoVo dbOrder = orderInfoService.addOrderInfo(orderInfoVo);
        // 如果邀请人没有关注公众号，则将金钱存到回佣记录中
        if (StringUtils.isBlank(userInfoVo.getWechatGzhOpenid())) {
            commissionCommonService.addCommission(redPacketVo.getInvitedUserId(),
                    redPacketVo.getUserId(),
                    redPacketVo.getAmount(),
                    dbOrder.getId(),
                    "gzh_redPacket");
            return;
        }
        try {
            // 如果邀请人已经关注公众号，则发送红包
            RedPacketResultVo redPacketResultVo = wechatService.sendRedPacket(event.getRedPacketVo());
            log.info("发送红包结果:{}", JSONObject.toJSONString(redPacketResultVo));
        } catch (WxPayException e) {
            log.error("发送红包异常:{}", JSONObject.toJSONString(e));
            switch (e.getErrCode()) {
                // 该用户今日领取红包个数超过限制。
                case "SENDNUM_LIMIT":
                    // 账号余额不足，请到商户平台充值后再重试
                case "NOTENOUGH":
                    // 超过频率限制,请稍后再试
                case "FREQ_LIMIT":
                    // 您的商户号今日发放金额超过限制，如有需要请登录微信支付商户平台更改API安全配置。
                case "SENDAMOUNT_LIMI":
                    // 该用户今日领取金额超过限制，如有需要请登录微信支付商户平台更改API安全配置。
                case "RCVDAMOUNT_LIMIT":
                    // 商户账户付款受限
                case "PAYER_ACCOUNT_ABNORMAL":
                    commissionCommonService.addCommission(redPacketVo.getInvitedUserId(),
                            redPacketVo.getUserId(),
                            redPacketVo.getAmount(),
                            dbOrder.getId(),
                            "gzh_redPacket");
                default:
                    log.info("未处理错误异常:{}", JSONObject.toJSONString(e));
            }
            log.error("发送红包异常:{}", JSONObject.toJSONString(e));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayUnifiedOrderV3Result.JsapiResult joinDatingWechat(DatingRegistrationInfoVo datingRegistrationInfoVo) throws Exception {
        DatingInfoResVo datingInfoResVo = datingInfoService.queryDatingInfo(datingRegistrationInfoVo.getDatingId(), null, "");
        if (datingInfoResVo == null || LocalDateTime.now().isAfter(datingInfoResVo.getStartTime())) {
            throw new SystemException(ResultEnum.DATING_REGISTRY_OVER);
        }
        UserActivityInfoVo joinEvent = userActivityInfoService.queryUserActivityInfoByUser(datingRegistrationInfoVo.getUserId());
        if (joinEvent == null) {
            throw new SystemException(ResultEnum.USER_NOT_PROFILE_COMPLETE.getCode(), "请完善个人信息");
        }
        // 如果存在则提示已报名
        LambdaQueryWrapper<DatingRegistrationInfo> query = Wrappers.<DatingRegistrationInfo>lambdaQuery().eq(DatingRegistrationInfo::getDatingId, datingRegistrationInfoVo.getDatingId())
                .eq(DatingRegistrationInfo::getUserId, datingRegistrationInfoVo.getUserId())
                .eq(DatingRegistrationInfo::getDeleteFlag, 0);
        DatingRegistrationInfo db = datingRegistrationInfoService.getOne(query);
        if (db != null) {
            throw new SystemException(ResultEnum.USER_ALREADY_JOIN_DATING);
        }
        if (datingRegistrationInfoVo.getPayAmount() == null || BigDecimal.ZERO.equals(datingRegistrationInfoVo.getPayAmount())) {
            throw new Exception("支付金额不能为0！");
        }
        BigDecimal payAmount = datingRegistrationInfoVo.getPayAmount();
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setUserId(datingRegistrationInfoVo.getUserId());
        orderInfoVo.setOrderNumber(OrderCodeUtils.generatorOrderNumber("JD"));
        orderInfoVo.setTotalAmount(payAmount);
        orderInfoVo.setStatus("PENDING");
        orderInfoVo.setPaymentMethod("WECHAT_APP");
        orderInfoVo.setPaymentTime(LocalDateTime.now());
        orderInfoVo.setOrderDescription("参加约会");
        orderInfoVo.setBusinessId(datingRegistrationInfoVo.getDatingId());
        orderInfoVo.setBusinessInfo(JSONObject.toJSONString(datingRegistrationInfoVo));
        orderInfoVo.setSource(null);
        orderInfoVo.setType("join_dating");
        OrderInfoVo dbOrder = orderInfoService.addOrderInfo(orderInfoVo);
        return wechatService.unifiedOrder(datingRegistrationInfoVo.getUserId(), payAmount.multiply(new BigDecimal("100")).intValue(),
                "join_dating", dbOrder.getOrderNumber(), dbOrder.getOrderDescription());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayUnifiedOrderV3Result.JsapiResult joinEventWechat(EventRegistrationInfoVo eventRegistrationInfoVo) throws Exception {
        EventInfoVo eventInfoVo = eventInfoService.queryEventInfo(eventRegistrationInfoVo.getEventId());
        if (eventInfoVo == null) {
            throw new Exception("活动不存在！");
        }
        // 如果存在则提示已报名
        LambdaQueryWrapper<EventRegistrationInfo> query = Wrappers.<EventRegistrationInfo>lambdaQuery().eq(EventRegistrationInfo::getEventId, eventRegistrationInfoVo.getEventId())
                .eq(EventRegistrationInfo::getUserId, eventRegistrationInfoVo.getUserId())
                .eq(EventRegistrationInfo::getDeleteFlag, 0);
        EventRegistrationInfo db = eventRegistrationInfoService.getOne(query);
        if (db != null) {
            throw new SystemException(ResultEnum.EVENT_ALREADY_REGISTERED);
        }
        // 开始之前之前的一天的23:59为报名截止日期
        log.info("开始时间：{}, kaishi:{}", eventInfoVo.getStartTime(), eventInfoVo.getStartTime().minusDays(1).withHour(23).withMinute(59));
        if (eventInfoVo.getStartTime().minusDays(1).withHour(23).withMinute(59).withSecond(59).isBefore(LocalDateTime.now())) {
            throw new Exception("活动已结束报名！");
        }
        // 校验报名人数是否超出设置
        if (eventInfoVo.getParticipantsCount() != null && eventInfoVo.getParticipantsCount() <= eventInfoVo.getRegistrationCount()) {
            throw new SystemException(ResultEnum.EVENT_MAX_REGISTERED);
        }
        UserActivityInfoVo joinEvent = userActivityInfoService.queryUserActivityInfoByUser(eventRegistrationInfoVo.getUserId());
        if (joinEvent == null) {
            throw new SystemException(ResultEnum.USER_NOT_PROFILE_COMPLETE.getCode(), "请完善个人信息");
        }
        if (eventRegistrationInfoVo.getPaymentAmount() == null || BigDecimal.ZERO.equals(eventRegistrationInfoVo.getPaymentAmount())) {
            throw new Exception("支付金额不能为0！");
        }
        if (eventRegistrationInfoVo.getRegistrationTime() == null) {
            eventRegistrationInfoVo.setRegistrationTime(LocalDateTime.now());
        }
        BigDecimal payAmount = eventRegistrationInfoVo.getPaymentAmount();
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setUserId(eventRegistrationInfoVo.getUserId());
        orderInfoVo.setOrderNumber(OrderCodeUtils.generatorOrderNumber("JE"));
        orderInfoVo.setTotalAmount(payAmount);
        orderInfoVo.setStatus("PENDING");
        orderInfoVo.setPaymentMethod("WECHAT_APP");
        orderInfoVo.setPaymentTime(LocalDateTime.now());
        orderInfoVo.setOrderDescription("参加活动");
        orderInfoVo.setBusinessId(eventRegistrationInfoVo.getEventId());
        orderInfoVo.setBusinessInfo(JSONObject.toJSONString(eventRegistrationInfoVo));
        orderInfoVo.setSource(null);
        orderInfoVo.setType("join_event");
        OrderInfoVo dbOrder = orderInfoService.addOrderInfo(orderInfoVo);
        return wechatService.unifiedOrder(eventRegistrationInfoVo.getUserId(),
                payAmount.multiply(new BigDecimal("100")).intValue(),
                "join_event", dbOrder.getOrderNumber(), dbOrder.getOrderDescription());
    }


}
